package com.vercon.otamirror.dialog;



import static com.vercon.otamirror.OtaActivity.homeSettingViewModel;

import android.annotation.SuppressLint;
import android.content.Intent;
import android.net.wifi.ScanResult;
import android.net.wifi.WifiManager;
import android.os.Bundle;
import android.os.Handler;
import android.os.StatFs;
import android.provider.Settings;
import android.view.View;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.ProgressBar;
import android.widget.TextView;
import android.widget.Toast;

import androidx.annotation.Nullable;

import com.abupdate.fotainject.FotaInject;
import com.abupdate.fotainject.FotaInjector;
import com.abupdate.iot_download_libs.DownEntity;
import com.abupdate.iot_libs.OtaAgentPolicy;
import com.abupdate.iot_libs.data.local.OtaEntity;
import com.abupdate.iot_libs.data.remote.VersionInfo;
import com.abupdate.iot_libs.engine.otaStatus.OtaStatus;
import com.abupdate.iot_libs.engine.otaStatus.OtaStatusMgr;
import com.abupdate.iot_libs.engine.policy.PolicyConfig;
import com.abupdate.iot_libs.engine.policy.PolicyManager;
import com.abupdate.iot_libs.interact.callback.ICheckVersionCallback;
import com.abupdate.iot_libs.interact.callback.IDownSimpleListener;
import com.abupdate.iot_libs.interact.callback.InstallListener;
import com.abupdate.iot_libs.utils.FileUtil;
import com.abupdate.iot_libs.utils.NetUtils;
import com.abupdate.sdk_annotation.Inject;
import com.vercon.commonmirror.Constants;
import com.vercon.commonmirror.cache.MirrorDataStorage;
import com.vercon.commonmirror.utils.APPUtil;
import com.vercon.commonmirror.utils.LogUtils;
import com.vercon.otamirror.MainActivity;
import com.vercon.otamirror.MainApplication;
import com.vercon.otamirror.R;
import com.vercon.otamirror.fragment.BaseFragment;

import com.vercon.otamirror.mode.FirmwareDownloadEvent;
import com.vercon.otamirror.mode.UpdateMode;

import com.vercon.otamirror.utils.helper.CleanUtils;
import com.vercon.otamirror.utils.helper.FragmentOpenManager;


import org.greenrobot.eventbus.EventBus;
import org.greenrobot.eventbus.Subscribe;
import org.greenrobot.eventbus.ThreadMode;
import org.jetbrains.annotations.NotNull;

import java.io.File;
import java.util.List;
import java.util.Map;

import butterknife.BindView;
import butterknife.OnClick;
import skin.support.utils.SkinPreference;

/**
 * Created by csh on 2021/4/13
 * 更新进度页
 */
public class UpdateFirmwareDialog extends BaseFragment  {

    private static final String TAG = UpdateFirmwareDialog.class.getSimpleName();
    @BindView(R.id.updathint)
    TextView updathint;
    @BindView(R.id.tv_progress)
    TextView tvProgress;
    @BindView(R.id.progressBar)
    ProgressBar progressBar;
    @BindView(R.id.ll_progress)
    LinearLayout llProgress;
    @BindView(R.id.btn_cancel)
    TextView btnCancel;
    @BindView(R.id.installProgressBar)
    ProgressBar installProgressBar;
    @BindView(R.id.iv_wifi)
    ImageView ivWifi;
    @BindView(R.id.ll_error)
    LinearLayout ll_error;
    @BindView(R.id.btn_cancel2)
    TextView btn_cancel2;

    @BindView(R.id.installhint)
    TextView installhint;

    private Handler mHandler;
    private int index;
    private UpdateMode mUpdateMode;
    private boolean isCancle = false;//是否取消下载

    public static boolean isUpdateIng = false;
    private final boolean isMandatory = false;//是否强制更新


    @Override
    protected int setContentView(@Nullable Bundle savedInstanceState) {
        return R.layout.fragment_update_firmware;
    }

    @Override
    protected void initView(View view) {
        EventBus.getDefault().register(this);
        isUpdateIng = true;
        mHandler = new Handler();
        installProgressBar.setVisibility(View.GONE);
        ll_error.setVisibility(View.GONE);
        if("gold".equals(SkinPreference.getInstance().getSkinName())){
            progressBar.setProgressDrawable(getResources().getDrawable(R.drawable.download_progress_gold));
        }else {
            progressBar.setProgressDrawable(getResources().getDrawable(R.drawable.download_progress));
        }

        llProgress.setVisibility(View.VISIBLE);

        if (getActivity() != null) {
            //更新关闭其他应用
            APPUtil.addPackageName("com.android.launcher3");//系统桌面

        }
        initdata();
        if (MainApplication.getContext().isForeground){
            MainApplication.getContext().setVirtualKey(false);
        }
        //initfirmwareData();

    }

    @Override
    public void onStart() {
        super.onStart();
        LogUtils.e("onStart" );
    }

    @Override
    protected void initListener(View view) {
        // wifi状态监听

    }


    @Override
    public void onResume() {
        super.onResume();
        LogUtils.e("onResume" );
        tvProgress.setText(String.format("%s%%", index));
//        mHandler.postDelayed(mRunnable, 1000);
    }


    @OnClick({R.id.btn_cancel, R.id.btn_download_again, R.id.iv_wifi, R.id.btn_cancel2})
    public void onViewClicked(View view) {
        if (view.getId() == R.id.btn_cancel) {
            if (btnCancel.getText().equals(getString(R.string.up_cancel))) {
                cancel();
            }
        } else if (view.getId() == R.id.btn_cancel2) {
            cancel();
        } else if (view.getId() == R.id.btn_download_again) {

        } else if (view.getId() == R.id.iv_wifi) {
            startActivity(new Intent(Settings.ACTION_WIFI_SETTINGS));
            APPUtil.addPackageName("com.android.settings.Settings");
        }


    }

    private void cancel() {
        CancelUpdateDialog dialog = new CancelUpdateDialog();
        dialog.setOnDialogListener(() -> {
            isCancle = true;
            //取消下载
            OtaAgentPolicy.download().downloadCancel();
            otaStatusMgr.refreshOtaStatus(OtaStatus.DOWNLOAD_PAUSE);
            CleanUtils.cleanAll();
            onBack();
            homeSettingViewModel.setOtaSwitchData(true);
        });
        dialog.show(getFragmentManager(), "");
    }

    private void setProgressLocation(int progress ){
        int width = progressBar.getWidth();
        LinearLayout.LayoutParams layoutParams;

        layoutParams = new LinearLayout.LayoutParams((int) getResources().getDimension(R.dimen.dp_65), (int) getResources().getDimension(R.dimen.dp_45));

        layoutParams.leftMargin = (int) ((width / 100f) * progress);
        tvProgress.setLayoutParams(layoutParams);
    }

    @Inject
    public OtaEntity mOtaEntity;
    private FotaInject fotaInject;
    @Inject
    public PolicyManager policyManager;
    private OtaStatusMgr otaStatusMgr;
    @Inject
    public VersionInfo versionInfo;


    private void showLoading(){

    }

    private void  initdata(){
        LogUtils.e("initdata" );
        //获取相关数据
        fotaInject = FotaInjector.inject(UpdateFirmwareDialog.this);
        otaStatusMgr = OtaStatusMgr.getInstance();
        PolicyConfig policyConfig = mOtaEntity.getPolicyManager().getPolicyConfig();
        //关闭电量检测
        policyConfig.request_battery(false);

        if (policyManager.isDownloadForce()){
            btnCancel.setVisibility(View.GONE);
        }else {
            btnCancel.setVisibility(View.VISIBLE);
        }

        cleardata();

    }

    private void cleardata(){
        //清理缓存，刷新状态-闲置
        otaStatusMgr.refreshOtaStatus(OtaStatus.IDLE);
        CleanUtils.cleanAll();
        getVersion();
    }

    private void getVersion() {
        installhint.setVisibility(View.GONE);
        LogUtils.e("getVersion" );
        if (otaStatusMgr == null){
            return;
        }
        OtaStatus aa = otaStatusMgr.getCurStatus();
        if (OtaStatus.IDLE != aa){
            return;
        }

        showLoading();
        /**
         * 检测版本
         * 异步回调请求方法，可以在子线程中调用，也可在主线程中调用，回调方法在主线程，便于UI处理。
         */
        OtaAgentPolicy.checkVersion().enqueue(new ICheckVersionCallback() {
            @Override
            public void onCheckSuccess(List<VersionInfo> infoList) {
                if (getContext() != null){
                    //发现有新版本
                    LogUtils.d("发现有新版本 " + infoList.size() + "  " + otaStatusMgr.getCurStatus());
                    for (VersionInfo info : infoList) {
                        LogUtils.d("版本 " + info.toString());
                    }

                    download();
                }
            }

            @Override
            public void onCheckFail(int errorCode) {
                //没有新版本
                LogUtils.e("没有新版本 " + errorCode);
                if (getContext() != null) {

                    if (errorCode == 3003) {//网络异常
                        Abnormalprompt(getString(R.string.download_failed), getString(R.string.download_failed_btn), 1);
                    } else {
                       // Toast.makeText(getActivity(), "没有新版本，错误码errorCode=" + errorCode, Toast.LENGTH_SHORT).show();
                    }
                }
            }
        });
    }

    @SuppressLint("SetTextI18n")
    private void download() {

        if (!NetUtils.isNetWorkAvailable()) {
            //网络是否可用
            Abnormalprompt(getString(R.string.download_failed), getString(R.string.download_failed_btn), 1);
            return;
        }
        String networkState = NetUtils.getNetworkState(MainApplication.sCx);
        boolean notSatisfiedWifiCondition = (policyManager.isRequestWifi() && !NetUtils.NETWORK_WIFI.equals(networkState));
        //是否为WiFi连接
        if (notSatisfiedWifiCondition) {
            //ToastUtils.showToast("请连接WiFi再下载");
            return;
        }
        //空间判断
        if (!policyManager.isStorageSpaceEnough(mOtaEntity.getFilePath())) {
           // Toast.makeText(getActivity(), "空间不足", Toast.LENGTH_SHORT).show();
            Abnormalprompt(getString(R.string.space_insufficient),getString(R.string.space_insufficient_btn),2);
            return;
        }

        /**
         * 异步下载
         * 可以在子线程中调用，也可在主线程中调用，回调方法在主线程，便于UI处理。
         */
        OtaAgentPolicy.download().enqueue(new IDownSimpleListener() {
            @Override
            public void onDownloadProgress(String productId, long downSize, long totalSize, int progress) {
                super.onDownloadProgress(productId, downSize, totalSize, progress);
                if (getContext() == null) return;
                //下载进度
                tvProgress.setText(progress + " %");
                setProgressLocation(progress);
                progressBar.setProgress(progress);
            }

            @Override
            public void on_start() {
                super.on_start();
                if (getContext() == null) return;
                //开始下载
                tvProgress.setText("0%");
                setProgressLocation(0);
                progressBar.setProgress(0);
            }

            @Override
            public void on_success(DownEntity downEntity) {
                super.on_success(downEntity);
                if (getContext() == null) return;
                //下载成功
                //Toast.makeText(getActivity(), "下载成功", Toast.LENGTH_SHORT).show();
//                installProgressBar.setVisibility(View.VISIBLE);
           //     btnCancel.setText(getString(R.string.updating));

            }

            @Override
            public void on_failed(DownEntity errDownEntity) {
                super.on_failed(errDownEntity);
                //下载失败
                LogUtils.d("下载失败: " + errDownEntity.toString());
                if (getContext() == null) return;
                //Toast.makeText(getActivity(), "下载失败", Toast.LENGTH_SHORT).show();

                Abnormalprompt(getString(R.string.download_failed),getString(R.string.download_failed_btn),1);
            }

            @Override
            public void onFinished(List<String> successProductIds, Map<String, Integer> failedProductIds) {
                super.onFinished(successProductIds, failedProductIds);
                if (getContext() == null) return;
                // 所有项目的升级包下载完成
                //Toast.makeText(getActivity(), "所有项目的升级包下载完成", Toast.LENGTH_SHORT).show();
                updateSystem();
            }

            @Override
            public void onCancel() {
                super.onCancel();
                if (getContext() == null) return;
                //下载取消
                //Toast.makeText(getActivity(), "下载取消", Toast.LENGTH_SHORT).show();

            }
        });

    }



    /**
     * 安装接口（会校验差分关系的版本号和升级文件的md5、电量，确保安全，请使用此升级接口）
     * 内部调用系统的升级接口：UpdateInter
     */
    private void updateSystem() {

        if (!new File(mOtaEntity.getFilePath()).exists()) {
            LogUtils.d("upgrade() file not exists");
            OtaStatusMgr.getInstance().refreshOtaStatus(OtaStatus.IDLE);
            Toast.makeText(getActivity(), "文件不存在", Toast.LENGTH_SHORT).show();
            return;
        }

        long internalAvailableSpace = getStorageSpace(mOtaEntity.getFilePath());
        double needSpace = (new File(mOtaEntity.getFilePath()).length() * 1.5f);
        LogUtils.d("internal available space: " + internalAvailableSpace + ", needSpace: " + needSpace);

        if (internalAvailableSpace < needSpace) {
            //ota 升级时，剩余空间小于升级包的 1.5 倍时提示失败
            OtaStatusMgr.getInstance().refreshOtaStatus(OtaStatus.IDLE);
           // Toast.makeText(getActivity(), "空间不足", Toast.LENGTH_SHORT).show();
            Abnormalprompt(getString(R.string.space_insufficient),getString(R.string.space_insufficient_btn),2);
            return;
        }
//        OtaStatusMgr.getInstance().refreshOtaStatus(OtaStatus.DOWNLOAD_FINISHED);
        update();
    }

    /**
     * 升级
     * FOTA必选功能
     */
    @SuppressLint("CheckResult")
    public void update() {
        installhint.setVisibility(View.VISIBLE);
        updathint.setText(R.string.updatingfirmware_update);
        tvProgress.setText( "0 %");
        setProgressLocation(0);
        progressBar.setProgress(0);
        OtaAgentPolicy.update()
                .install(mOtaEntity.getProductInfo().productId, new InstallListener() {

                    @SuppressLint("SetTextI18n")
                    @Override
                    public void onUpgradeProgress(int tag, int progress) {
                        LogUtils.e("升级进度：" + tag + "  " + progress);
                        if (getContext() == null) return;
                        tvProgress.setText( progress + " %");
                        setProgressLocation(progress);
                        progressBar.setProgress(progress);
                        if (progress == 100) {
                            onUpgradeSuccess();
                        }
                    }

                    @Override
                    public void onUpgradeSuccess() {
                        LogUtils.e("升级成功");
                        if (getContext() == null) return;
                       // Toast.makeText(getActivity(), "升级成功", Toast.LENGTH_SHORT).show();
                        MirrorDataStorage.instance().storeObject(Constants.Firmware_Save, null);//如果升级，就清空推送的记录
                        //重启
                        new Handler().postDelayed(() -> {
                            MainApplication.reboot();
                        }, 2000);
                    }

                    @Override
                    public void onUpgradeFail(int code) {
                        LogUtils.e("升级失败：" + code);
                        if (getContext() == null) return;
                       // Toast.makeText(getActivity(), "升级失败：" + code, Toast.LENGTH_SHORT).show();
                        Abnormalprompt(getString(R.string.check_failure),getString(R.string.check_failure_btn),3);
                    }
                });
    }
    /**
     * 下载对剩余空间的要求
     *
     * @param path
     * @return 需要的空间size
     */
    private long getStorageSpace(String path) {
        File file = new File(path);
        String verify_path = file.getParentFile().getAbsolutePath();
        boolean existsDir = FileUtil.createOrExistsDir(verify_path);
        if (!existsDir) {
            //文件路径不合法
            throw new IllegalArgumentException("Invalid path:" + path);
        }
        StatFs statfs = new StatFs(verify_path);
        long blockSize = 0;
        long blockCount = 0;
        if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.JELLY_BEAN_MR2) {
            blockSize = statfs.getBlockSizeLong();
            blockCount = statfs.getAvailableBlocksLong();
        } else {
            blockSize = statfs.getBlockSize();
            blockCount = statfs.getBlockCount();
        }
        return blockSize * blockCount;
    }

    /**
     * 异常提示
     * @param content
     * @param commit
     * @param id
     */
    private void Abnormalprompt(String content,String commit,int id){
        DownloadfailedDialog dialog = new DownloadfailedDialog();
        dialog.setString(content,commit);
        dialog.setOnDeleteDialogListener(new DownloadfailedDialog.OnDeleteDialogListener() {
            @Override
            public void sure() {
                dialog.dismiss();
                if (id == 1){//网络异常

                }else if (id == 2){//空间不够

                }
                else if (id == 3){//下载完成之后升级失败
                    CleanUtils.cleanAll();
                    onBack();
                }
            }
        });
        dialog.show(getFragmentManager(), "");
    }

    //休眠回调
    @Subscribe(threadMode = ThreadMode.MAIN_ORDERED)
    public void MessageEvent(FirmwareDownloadEvent event) {
        LogUtils.d(TAG, "切换WiFi回来，继续获取版本=:" );
        getVersion();
    }

    @Override
    public void onDestroyView() {
        EventBus.getDefault().unregister(this);
        isCancle = true;
        isUpdateIng = false;
        OtaAgentPolicy.download().downloadCancel();
        if (fotaInject != null) {
            fotaInject.unInject();
        }



        super.onDestroyView();

    }

}